// Proxy 可以理解成，在目标对象之前架设一层“拦截”，外界对该对象的访问，
// 都必须先通过这层拦截，因此提供了一种机制，可以对外界的访问进行过滤和改写。
// 常见的 Proxy 支持的拦截操作方法
// get(target, propKey, receiver) 拦截对象属性的读取
// set(target, propKey, value, receiver) 拦截对象属性的设置，返回一个布尔值。
// has(target, propKey) 拦截propKey in proxy的操作，以及对象的hasOwnProperty方法，返回一个布尔值。
// deleteProperty(target, propKey) 拦截delete proxy[propKey]的操作，返回一个布尔值。
// apply(target, object, args) 拦截 Proxy 实例作为函数调用的操作，比如proxy(...args)、proxy.call(object, ...args)、proxy.apply(...)。
// construct(target, args) 拦截 Proxy 实例作为构造函数调用的操作，比如new proxy(...args)。

// 在支持 Proxy 的浏览器环境中，Proxy 是一个全局对象，可以直接使用。
// Proxy(target, handler) 是一个构造函数，target 是被代理的对象，
// handlder 是声明了各类代理操作的对象，最终返回一个代理对象。
// 外界每次通过代理对象访问 target 对象的属性时，就会经过 handler 对象，
// 从这个流程来看，代理对象很类似 middleware（中间件）。

const target = {
    name: 'Billy Bob',
    age: 15
};

const handler = {
    get(target, key, proxy) {
        const today = new Date();
        console.log(`GET request made for ${key} at ${today}`);

        return Reflect.get(target, key, proxy);
    }
};

const proxy = new Proxy(target, handler);
console.log(proxy.name);
